#include <iostream>

using std::cout;
using std::endl;


// 直接找系统要
inline static void* SystemAlloc(size_t kpage){
#ifdef _WIN32
#include <windows.h>
void* ptr = VirtualAlloc(0, kpage*(1 << 12), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
#else
void* ptr = malloc(kpage);
#endif
    if(ptr == nullptr) throw std::bad_alloc();

    return ptr;
}

template <class T>
class ObjectPool
{
public:
    T *New()
    {
        T *obj = nullptr;
        size_t objsize = sizeof(T) < sizeof(void *) ? sizeof(void *) : sizeof(T); // objsize 存储实际给了 T 多少字节

        // 先找 freelist 要空间
        if (_freelist)
        {
            obj = (T *)_freelist;
            _freelist = *(void **)_freelist;
        }
        else
        {
            if (_memory == nullptr || _remainByte < objsize)
            {
                _remainByte = 128 * 1024;
                _memory = (char *)SystemAlloc(_remainByte);
                if (!_memory)
                {
                    throw std::bad_alloc();
                }
            }
            obj = (T*)_memory;

            _memory += objsize;
            _remainByte -= objsize;
        }
        new(obj)T;//调用默认构造

        return obj;
    }
    void Delete(T* obj){
        obj->~T();
        *(void**)obj = _freelist;
        _freelist = obj;
    }
private:
    char *_memory = nullptr;    // 内存地址
    size_t _remainByte = 0;     // 剩余字节数
    void *_freelist = nullptr;  // 自由链表
};